//
//  EPCameraViewController.swift
//  EPHome
//
//  Created by  on 2022/9/6.
//

import UIKit
import AVFoundation
//enum EPCameraViewType : Int
//{
//    case normal = 1
//    case qr = 2
//}
//
//protocol EPCameraViewDelegate{
//
//    /// 代理
//    /// - Parameters:
//    ///   - imgData: 拍照或者相册完成的，得到的图片data
//    ///   - resultString: 二维码扫描完成后识别的连接
//    func finished(_ imgData:NSData?, _ resultString:String)
//    func maskLayer(_ maskLayer:CALayer,_ scanView:UIView)
//}
//
//extension EPCameraViewDelegate{
//    func maskLayer(_ maskLayer:CALayer,_ scanView:UIView){
//
//    }
//}

class EPCameraViewController: UIViewController {
   weak var delegate:EPCameraViewDelegate?

    ///由他把输入输出结合在一起，并开始启动捕获设备（摄像头）
    lazy var session:AVCaptureSession={return AVCaptureSession()}()
    ///摄像头
    lazy var device:AVCaptureDevice={return AVCaptureDevice.default(for: .video)}()!
    ///输入
    lazy var input:AVCaptureDeviceInput={return try? AVCaptureDeviceInput(device:self.device)}()!
    /// 输出图片
    lazy var imgOutput:AVCaptureStillImageOutput={return AVCaptureStillImageOutput()}()
    ///二维码输出
    lazy var output:AVCaptureMetadataOutput={
        let out = AVCaptureMetadataOutput()
        out.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        return out
    }()
    ///创建图像预览层，实时显示捕获到图像
   private lazy var previewLayer:AVCaptureVideoPreviewLayer={
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.videoGravity = .resizeAspectFill
        return layer
    }()
    
    var preView = UIView(){
        didSet{
            self.previewLayer.frame = preView.bounds
            preView.layer.addSublayer(self.previewLayer)
            self.view.addSubview(preView)

        }
    }
    
    var type:EPCameraViewType = .normal{
        didSet{
            if self.session.canAddInput(self.input){
                self.session.addInput(self.input)
            }
            switch type {
            case .normal:
                if self.session.canAddOutput(self.imgOutput){
                    self.session.addOutput(self.imgOutput)
                }
            case .qr:
                if self.session.canAddOutput(self.output){
                    self.session.addOutput(self.output)
                }
                self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes
            }
            self.session.startRunning()
        }
    }
    /// 打开相册
    func openAlbum()
    {
        let vc = UIImagePickerController()
        vc.delegate = self
        vc.allowsEditing = true
        vc.sourceType = UIImagePickerController.SourceType.savedPhotosAlbum
        vc.modalPresentationStyle = .fullScreen
        self.present(vc, animated:true)
    }
    
    ///拍照
    func takePhone()
    {
        let connection = self.imgOutput.connection(with: .video) ?? nil
        if connection == nil{
            return print("拍照失败!")
        }
        self.imgOutput.captureStillImageAsynchronously(from: connection!) { buff, error in
            if buff == nil {return }
            let imgData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buff!)
            self.delegate?.finished(imgData! as NSData, "")
            self.session.stopRunning()
        }
    }
    
    
    /// 切换闪光灯
    func flash(_ open:Bool)
    {
        if self.device.hasFlash{
            try? self.device.lockForConfiguration()
            self.device.flashMode = open ? .on : .off
            self.device.unlockForConfiguration()
        }
    }
    
    ///切换摄像头
    func changeCamera()
    {
        let count = AVCaptureDevice.devices(for: .video).count
        if count < 2{
            print("只有一个摄像头")
            return
        }
        /// 另一个摄像头的位置
        let position:AVCaptureDevice.Position = self.input.device.position == .front ? .back : .front
        let subtype:CATransitionSubtype = position == .back ? .fromLeft : .fromRight
        let newCamera:AVCaptureDevice = self.cameraPosition(position)!
        
        ///镜头反转动画
        let animation = CATransition()
        animation.duration = 0.5
        animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
        animation.type = CATransitionType.init(rawValue:"oglFlip")
        animation.subtype = subtype///翻转方向
        
        //生成新的输入
        let newInput = try? AVCaptureDeviceInput.init(device: newCamera)
        self.previewLayer.add(animation, forKey: nil)
        if (newInput != nil) {
            self.session.beginConfiguration()
            if self.session.canAddInput(newInput!){
                self.session.removeInput(self.input)
                self.session.addInput(newInput!)
                self.input = newInput!
            }
            self.session.commitConfiguration()
        }
        
    }
    ///获取相机位置
    private func cameraPosition(_ position:AVCaptureDevice.Position)->AVCaptureDevice?
    {
        let devices = AVCaptureDevice.devices(for: .video)
        for device in devices {
            if device.position == position{return device}
        }
        return nil
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.type = .qr
    }
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.session.stopRunning()
    }
}


//MARK: - 相册代理 UIImagePickerControllerDelegate/UINavigationControllerDelegate
extension EPCameraViewController : UIImagePickerControllerDelegate , UINavigationControllerDelegate
{
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let img : UIImage = info[UIImagePickerController.InfoKey.editedImage] as! UIImage
        let data = img.pngData()
        self.delegate?.finished(data! as NSData, "")
        picker.dismiss(animated: true) { }
    }
}

//MARK: - 扫描二维码代理 AVCaptureMetadataOutputObjectsDelegate
extension EPCameraViewController : AVCaptureMetadataOutputObjectsDelegate
{
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if metadataObjects.count > 0{
            let obj = metadataObjects.last as? AVMetadataMachineReadableCodeObject ?? nil
            if obj == nil {return}
            let result = obj!.stringValue
            self.delegate?.finished(nil, result!)
            self.session.stopRunning()
        }
    }
}
